use std::{fs, path::Path, time::SystemTime};

use crate::{
    config::AppContext,
    domain::topic::Topic,
    service::topic_service,
    utils::{self},
    ApiResponse, CommParam, DATA_ROOT, FILE_PATH, STATIC_PATH,
};
use axum::{
    extract::{Multipart, Query},
    response::IntoResponse,
    Form,
};
use dirs::home_dir;

use random::Source;
use tokio::{fs::File, io::AsyncWriteExt};

pub async fn save(topic: Form<Topic>) -> impl IntoResponse {
    let mut topic = topic.0;
    let res = if topic.id.unwrap_or_default() == 0 {
        topic.id = None;
        topic_service::save(&mut topic).await
    } else {
        topic_service::update(&mut topic).await
    };
    ApiResponse::from(res.unwrap())
    // Redirect::to("/index")
}

pub async fn rebuild_index() -> impl IntoResponse {
    let mut data_dir = utils::data_dir();
    data_dir.push_str("/index");
    if Path::new(data_dir.as_str()).exists() {
        fs::remove_dir_all(data_dir).unwrap();
    }
    let _ = topic_service::rebuild_index().await;
    ApiResponse::from(1)
}
pub async fn del(topic: Form<Topic>) -> impl IntoResponse {
    let topic = topic.0;
    assert!(topic.id.unwrap_or_default() > 0, "参数错误");
    let _ = topic_service::delete(topic).await;
    ApiResponse::from(1)
}

pub async fn top(topic: Form<Topic>) -> impl IntoResponse {
    let topic = topic.0;
    assert!(topic.id.unwrap_or_default() > 0, "参数错误");
    let _ = Topic::update_by_column_skip(AppContext::rbatis(), &topic, "id", true).await;
    ApiResponse::from(1)
}

pub async fn pass(topic: Form<Topic>) -> impl IntoResponse {
    let topic = topic.0;
    assert!(topic.id.unwrap_or_default() > 0, "参数错误");
    let db = topic_service::select_by_id(topic.id.unwrap()).await;
    if topic.pass == db.pass {
        return ApiResponse::from(db.content.unwrap());
    }
    ApiResponse::from_error("密码错误")
}

pub async fn upload(param: Query<CommParam>, mut multipart: Multipart) -> impl IntoResponse {
    let param = param.0;
    let _thum = param.thum.map_or(false, |_| true);
    let mut path = String::new();
    while let Ok(Some(mut field)) = multipart.next_field().await {
        if let Some(_) = field.file_name() {
            //文件处理
            let content_type = field.content_type().unwrap().to_string();
            if !content_type.starts_with("image/") {
                return ApiResponse::from_error("请上传图片格式");
            }
            //根据文件类型生成随机文件名(出于安全考虑)
            let seed = SystemTime::now()
                .duration_since(SystemTime::UNIX_EPOCH)
                .unwrap()
                .as_nanos() as u64;
            let read = random::default(seed).read::<f32>();
            let rnd = (read * 1000000000 as f32) as i32;
            let index = content_type
                .find("/")
                .map(|i| i)
                .unwrap_or(usize::max_value());
            //文件扩展名
            let mut ext_name = "jpg";
            if index != usize::max_value() {
                ext_name = &content_type[index + 1..];
            }

            path = format!(
                "{}/{}/{}/{}.{}",
                STATIC_PATH, FILE_PATH, "temp", rnd, ext_name
            );
            let mut dest_file = home_dir().unwrap();
            dest_file.push(DATA_ROOT);
            dest_file.push(path.as_str());

            let mut file = File::create(dest_file.as_path()).await.unwrap();
            while let Ok(chun_data) = field.chunk().await {
                if let Some(bytes_data) = chun_data {
                    file.write_all(&bytes_data).await.unwrap();
                } else {
                    break;
                }
            }
            // if thum {
            //     // 创建缩略图
            //     let img = image::open(dest_file.clone()).unwrap();
            //     let thumbnail = resize(&img, 180, 120, FilterType::Gaussian);
            //     thumbnail.save(dest_file).unwrap();
            // }
            continue;
        }
        //其它参数处理
        let _ = field.text().await;
    }
    path.insert(0, '/');
    return ApiResponse::from(path);
}
